package info.marlan.util;

import info.marlan.sipgate.R;
import info.marlan.sipgate.WidgetProvider;
import info.marlan.sipgate.model.HistoryEntry;
import info.marlan.sipgate.model.OwnUri;
import info.marlan.sipgate.model.PhoneBookEntry;
import info.marlan.sipgate.model.PriceType;

import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.xmlrpc.android.XMLRPCException;
import org.xmlrpc.android.XMLRPCMethod;

import android.util.Log;

public class ConvertUtil {
	public static NumberFormat formatter = new DecimalFormat("#0.00");
	public static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
	public static SimpleDateFormat sqlDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	public static SimpleDateFormat displayDateFormat = new SimpleDateFormat("MM/dd HH:mm");
	public static String[] STATUS_CODES = new String[]{ "sip:1100","sip:1000","sip:1200","sip:2100","sip:2000","sip:2200","sip:2300","sip:2400","sip:3000","sip:3100","sip:1020","sip:4000"};
	public static String STATUS_CODE_REPLACEMENT = "sip:00";
	public static List<HistoryEntry> getHistoryEntries(Object obj, int widgetId) throws XMLRPCException{
		
		Map<String,Object> r = (Map<String,Object>)obj;
		validateResult(r);
		List<HistoryEntry> historyEntries = new ArrayList<HistoryEntry>();
		Object[] l = (Object[]) r.get(HistoryEntry.HISTORY);
		for(Object m:l){
			Map<String,Object> h = (Map<String,Object>)m;
			HistoryEntry historyEntry = new HistoryEntry();
			historyEntry.setEntryID((String)h.get(HistoryEntry.ENTRYID));
			try {
				historyEntry.setTimestamp(dateFormat.parse((String)h.get(HistoryEntry.TIMESTAMP)));
			} catch (ParseException e) {
				Log.e(WidgetProvider.LOGTAG, (String)h.get(HistoryEntry.TIMESTAMP));
			}
			historyEntry.settOS((String)h.get(HistoryEntry.TOS));
			historyEntry.setLocalUri((String)h.get(HistoryEntry.LOCALURI));
			historyEntry.setRemoteUri((String)h.get(HistoryEntry.REMOTEURI));
			historyEntry.setStatus((String)h.get(HistoryEntry.STATUS));	
			historyEntry.setWidgetId(widgetId);
			historyEntries.add(historyEntry);
		}
		return historyEntries;
	}
	
	public static void validateResult(Map<String,Object> result) throws XMLRPCException{
		Integer statusCode = (Integer)result.get(HistoryEntry.STATUSCODE);
		if(statusCode == null ){
			throw new XMLRPCException("Statuscode is missing",XMLRPCMethod.STATUSCODE_MISSING_STATUSCODE);
		}
		if(statusCode.intValue()!=XMLRPCMethod.STATUSCODE_SUCCESS){
			String statusMessage = (String)result.get(HistoryEntry.STATUSSTRING);
			throw new XMLRPCException(statusMessage,statusCode.intValue());
		}
	}
	
	public static List<OwnUri> getOwnUriList(Object obj, int widgetId)throws XMLRPCException{
		
		Map<String,Object> r = (Map<String,Object>)obj;
		validateResult(r);
		List<OwnUri> ownUriList = new ArrayList<OwnUri>();
		Object[] l = (Object[]) r.get(OwnUri.OWNURILIST);
		for(Object m:l){
			Map<String,Object> h = (Map<String,Object>)m;
			OwnUri ownUri = new OwnUri();
			ownUri.setDefaultUri((Boolean)h.get(OwnUri.DEFAULTURI));
			ownUri.setE164Out((String)h.get(OwnUri.E164OUT));
			ownUri.setSipUri((String)h.get(OwnUri.SIPURI));
			ownUri.setUriAlias((String)h.get(OwnUri.URIALIAS));
			Object[] e = (Object[])h.get(OwnUri.E164IN);
			Object[] t = (Object[])h.get(OwnUri.TOS);
			if(e!=null && e.length>0){
				List<String> elements = new ArrayList<String>();
				for(Object o:e){
					String element = (String)o;
					elements.add(element);
				}
				ownUri.setE164In( elements);
			}
			if(t!=null && t.length>0){
				List<String> elements = new ArrayList<String>();
				for(Object o:t){
					String element = (String)o;
					elements.add(element);
				}
				ownUri.settOS(( elements));
			}
				
			ownUriList.add(ownUri);
		}
		return ownUriList;
	}
	
	
	public static PriceType getBalance(Object obj, int widgetId) throws XMLRPCException{
		
		Map<String,Object> r = (Map<String,Object>)obj;
		validateResult(r);
		PriceType balance = new PriceType();
		Map<String,Object> m = (Map<String,Object>) r.get(PriceType.CURRENTBALANCE);
		if(m!=null){
			balance.setCurrency((String)m.get(PriceType.CURRENCY));
			balance.setTotalIncludingVat((Double)m.get(PriceType.TOTALINCLUDINGVAT));
			balance.setTotalExcludingVat((Double)m.get(PriceType.TOTALEXCLUDINGVAT));
			balance.setVatAmount((Double)m.get(PriceType.VATAMOUNT));
			balance.setVatPercent((Double)m.get(PriceType.VATPERCENT));
			balance.setWidgetId(widgetId);
		}else{
			return null;
		}

		return balance;
	}
	
	public static List<PhoneBookEntry> getPhoneBookEntries(Object obj, int widgetId, List<String> entryList) throws XMLRPCException{
		
		Map<String,Object> r = (Map<String,Object>)obj;
		validateResult(r);
		List<PhoneBookEntry> phoneBookEntries = new ArrayList<PhoneBookEntry>();
		Object[] l = (Object[]) r.get(PhoneBookEntry.PHONEBOOKLIST);
		for(Object m:l){
			Map<String,Object> h = (Map<String,Object>)m;
			PhoneBookEntry phoneBookEntry = new PhoneBookEntry();
			phoneBookEntry.setEntryID((String)h.get(PhoneBookEntry.ENTRYID));
			phoneBookEntry.setEntryHash((String)h.get(PhoneBookEntry.ENTRYHASH));
			phoneBookEntries.add(phoneBookEntry);
			if(entryList!=null){
				entryList.add(phoneBookEntry.getEntryID());
			}
		}
		return phoneBookEntries;
	}
	
	public static PhoneBookEntry findPhoneBookEntry(List<PhoneBookEntry> phoneBookEntries, String entryId){
		if(phoneBookEntries==null || entryId==null){
			return null;
		}
		for(PhoneBookEntry entry:phoneBookEntries){
			if(entryId.equals(entry.getEntry())){
				return entry;
			}
		}
		return null;
	}
	
	public static List<PhoneBookEntry> updatePhoneBookEntries(Object obj, int widgetId, List<PhoneBookEntry> phoneBookEntries) throws XMLRPCException{
		
		Map<String,Object> r = (Map<String,Object>)obj;
		validateResult(r);
		
		Object[] l = (Object[]) r.get(PhoneBookEntry.ENTRYLIST);
		for(Object m:l){
			Map<String,Object> h = (Map<String,Object>)m;
			PhoneBookEntry phoneBookEntry = findPhoneBookEntry(phoneBookEntries,(String)h.get(PhoneBookEntry.ENTRYID));
			if(phoneBookEntry==null){
				phoneBookEntry = new PhoneBookEntry();
				phoneBookEntries.add(phoneBookEntry);
				phoneBookEntry.setEntryID((String)h.get(PhoneBookEntry.ENTRYID));
			}
			phoneBookEntry.setEntryHash((String)h.get(PhoneBookEntry.ENTRYHASH));
			phoneBookEntry.setEntry(((String)h.get(PhoneBookEntry.ENTRY)));
			phoneBookEntry.setWidgetId(widgetId);
			
		}
		return phoneBookEntries;
	}
	
	public static String getSQLTimestamp(Date date){
		return sqlDateFormat.format(date);
	}
	
	public static Date getTimestampFromSQL(String date){
		Date d = null;
		try {
			d = sqlDateFormat.parse(date);
		} catch (ParseException e) {
			
		}
		return d;
	}
	
	public static String getBaseNumber(String sipNumber){
		if(sipNumber==null){
			return "";
		}
		if(sipNumber.indexOf("@")<5 || sipNumber.length()<5){
			return sipNumber;
		}
		for(String code : STATUS_CODES){
			sipNumber = sipNumber.replaceFirst(code, STATUS_CODE_REPLACEMENT);
		}
		return sipNumber.substring(4, sipNumber.indexOf("@"));
	}
	
	public static String getCallNumber(String sipNumber){
		return "tel:00" + getBaseNumber(sipNumber);
	}
	
	public static String getDisplayTimestamp(Date date){
		return displayDateFormat.format(date) + "h";
	}

	public static int getStatusIcon(String status){
		if(HistoryEntry.STATUSACCEPTED.equalsIgnoreCase(status)){
			return R.drawable.icon_received;
		}
		if(HistoryEntry.STATUSMISSED.equalsIgnoreCase(status)){
			return R.drawable.icon_missed;
		}
		if(HistoryEntry.STATUSOUTGOING.equalsIgnoreCase(status)){
			return R.drawable.icon_called;
		}
		return R.drawable.icon_called;
	}
	public static String formatBalance(PriceType balance){
		if(balance==null){
			return "";
		}
		return formatter.format(balance.getTotalIncludingVat()) + " " + balance.getCurrency();
		
	}
}
